<?php


namespace services\linkedcare;

use common\components\Service;
use common\helpers\CommonHelper;
use common\helpers\DateHelper;
use common\helpers\RedisHelper;
use common\models\linkedcare\LinkedcarePatients;
use common\models\linkedcare\LinkedcarePatientsRecord;
use common\models\patient\Patient;
use common\models\patient\PatientType;
use services\patient\PatientOrderService;
use services\spoker\SpokerService;
use Yii;

class LinkedcarePatientsRecordService extends Service
{
    /**
     * 到店列表
     * @param array $params
     * @param int $page
     * @param int $pageSize
     * @return array
     */
    public function getListPage(array $params = [], int $page = 0, int $pageSize = 0): array
    {
        $query = LinkedcarePatientsRecord::find()->alias('lpr')
            ->select([
                'lpr.startTime start_time', 'lpr.doctorName doctor_name', 'lpr.consultantName consultant_name',
                'lp.officeName shop_name',
                'p.id', 'p.name', 'p.type_id', 'p.last_order_id',
            ])
            ->innerJoin(LinkedcarePatients::tableName().' lp', 'lp.privateId = lpr.privateId')
            ->innerJoin(Patient::tableName().' p', 'p.mobile = lp.mobile')
            ->where([
                'p.user_id' => Yii::$app->user->identity->member_id,
                'p.status' => Patient::STATUS_ENABLE
            ]);
        if (isset($params['name']) && $params['name']) {
            $query->andWhere(['like', 'p.name', $params['name']]);
        }
        // 排序
        $order = [
            'lpr.startTime' => SORT_DESC,
            'lpr.id' => SORT_DESC,
        ];

        return $this->getListPageRes($query, $page, $pageSize, $order);
    }

    /**
     * 格式化列表
     * @param array $data
     * @return array
     */
    public function getListPageFormat(array $data = []): array
    {
        // 最近一次预约记录
        $patientOrderMap = PatientOrderService::getPatientOrderMap(array_column($data, 'last_order_id'));
        $list = [];
        foreach ($data as $row) {
            $treatmentProjectId = $patientOrderMap[$row['id']]->treatment_project_id ?? 0;
            $treatmentProject = RedisHelper::getTreatmentProject($treatmentProjectId);
            $patientType = RedisHelper::getPatientType($row['type_id']);
            $list[] = [
                'id' => $row['id'],
                'name' => $row['name'],
                'shop_name' => $row['shop_name'],
                'doctor_name' => $row['doctor_name'],
                'consultant_name' => $row['consultant_name'],
                'treatment_project' => $treatmentProject ? $treatmentProject->name : '',
                'type_str' => $patientType && $patientType->status != PatientType::STATUS_DELETE ? $patientType->name : '',
                'arrive_time_str' => DateHelper::timestampToDate(strtotime($row['start_time']), DateHelper::DATE_FORMAT_4),
            ];
        }
        return $list;
    }

    /**
     * 统计用户到店患者数
     * @return int
     */
    public static function getUserArriveNum(array $params = []): int
    {
        $query = LinkedcarePatientsRecord::find()->alias('lpr')
            ->innerJoin(LinkedcarePatients::tableName().' lp', 'lp.privateId = lpr.privateId')
            ->innerJoin(Patient::tableName().' p', 'p.mobile = lp.mobile')
            ->where([
                'p.user_id' => Yii::$app->user->identity->member_id,
                'p.status' => Patient::STATUS_ENABLE
            ]);
        if (isset($params['patient_id']) && $params['patient_id']) {
            $query->andWhere(['p.id' => $params['patient_id']]);
        }
        if (isset($params['start_time']) && $params['start_time']) {
            $query->andWhere(['>=', 'lpr.startTime', $params['start_time']]);
        }
        if (isset($params['end_time']) && $params['end_time']) {
            $query->andWhere(['<=', 'lpr.startTime', $params['end_time'].' 23:59:59']);
        }
        $total = $query->count();
        return $total ?: 0;
    }

    /**
     * 获取患者新增月账单统计
     * @return array
     */
    public static function getMonthBillByUser(array $params): array
    {
        $query = Patient::find()->alias('p')
            ->select(['p.user_id', 'COUNT(*) arrive_num'])
            ->innerJoin(LinkedcarePatients::tableName().' lp', 'lp.mobile = p.mobile')
            ->innerJoin(LinkedcarePatientsRecord::tableName().' lpr', 'lpr.privateId = lp.privateId')
            ->where([
                'p.status' => Patient::STATUS_ENABLE
            ])
            ->groupBy('p.user_id');
        if (isset($params['start_time']) && $params['start_time']) {
            $query->andWhere(['>=', 'lpr.startTime', $params['start_time']]);
        }
        if (isset($params['end_time']) && $params['end_time']) {
            $query->andWhere(['<=', 'lpr.startTime', $params['end_time'].' 23:59:59']);
        }
        return $query->having(['>', 'arrive_num', 0])->indexBy('user_id')->asArray()->all();
    }

    /**
     * 统计到店患者数排行榜
     * @return array
     */
    public static function getRankList(array $params = []): array
    {
        $query = Patient::find()->alias('p')
            ->select(['p.spoker_id', 'COUNT(*) arrive_num', 'MAX(lpr.startTime) start_time'])
            ->innerJoin(LinkedcarePatients::tableName().' lp', 'lp.mobile = p.mobile')
            ->innerJoin(LinkedcarePatientsRecord::tableName().' lpr', 'lpr.privateId = lp.privateId')
            ->where([
                'p.status' => Patient::STATUS_ENABLE
            ])
            ->groupBy('p.spoker_id');
        if (isset($params['start_time']) && $params['start_time']) {
            $query->andWhere(['>=', 'lpr.startTime', $params['start_time']]);
        }
        if (isset($params['end_time']) && $params['end_time']) {
            $query->andWhere(['<=', 'lpr.startTime', $params['end_time'].' 23:59:59']);
        }
        $list = $query
            ->orderBy([
                'arrive_num' => SORT_DESC,
                'start_time' => SORT_ASC,
            ])
            ->limit(10)
            ->asArray()
            ->all();
        // 代言人集合
        $spokerMap = SpokerService::getMapByIds(array_column($list, 'spoker_id'));
        $listFormat = [];
        foreach ($list as $row) {
            $listFormat[] = [
                'spoker_id' => $row['spoker_id'],
                'arrive_num' => $row['arrive_num'],
                'name' => CommonHelper::getRankNameStr($spokerMap[$row['spoker_id']]->name ?? ''),
            ];
        }
        return $listFormat;
    }
}
